home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / science / ack3d.zip / ACKRAY.C < prev    next >
Text File  |  1994-01-09  |  7KB  |  237 lines

  1. /******************* ( Animation Construction Kit 3D ) ***********************/
  2. /*              Ray Casting Routines                     */
  3. /* CopyRight (c) 1993       Author: Lary Myers                     */
  4. /*****************************************************************************/
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <dos.h>
  9. #include <mem.h>
  10. #include <alloc.h>
  11. #include <io.h>
  12. #include <fcntl.h>
  13. #include <time.h>
  14. #include <string.h>
  15. #include <sys\stat.h>
  16. #include "ack3d.h"
  17. #include "ackeng.h"
  18. #include "ackext.h"
  19.  
  20.         UCHAR   yLight;
  21.         UCHAR   xLight;
  22.  
  23.  
  24. /****************************************************************************
  25. ** This routine cast rays along the X walls of the map to determine when   **
  26. ** a wall is struck. A zero returned indicates no wall was found, else the **
  27. ** bitmap number of the wall is returned.                   **
  28. ** If a wall is found the variables LastY1 and iLastX are set to the map   **
  29. ** coordinates of the wall and xMapPosn is the actual map coordinate.       **
  30. **                                       **
  31. ****************************************************************************/
  32. UINT xRay(int x,int y,int angle,ACKENG *ae)
  33. {
  34.     UINT    Color;
  35.     int        i,j,mx,my;
  36.     int        TablePosn;
  37.     int        MapPosn,CurPosn;
  38.     int        xBeg;
  39.     long    xPos,xNext;
  40.     int        BitmapColumn;
  41.     int        xCenter,yCenter,xAdj;
  42.     int        ObjPosn;
  43.     int        oBegX,oBegY;
  44.     long    yPos;
  45.     long    yNext;
  46.     long    xd,yd,sy;
  47.     long    ObjDist;
  48.  
  49. xBeg  = x & 0xFFC0;        /* Get upper left corner of square    */
  50. yNext = yNextTable[angle];    /* PreCalc'd value of 64 * Tan(angle) */
  51.  
  52. if (angle > INT_ANGLE_270 || angle < INT_ANGLE_90)
  53.     {
  54.     xPos  = xBeg + GRID_SIZE;    /* Looking to the right */
  55.     xNext = GRID_SIZE;        /* Positive direction    */
  56.     }
  57. else
  58.     {
  59.     xPos  = xBeg;        /* Looking to the left    */
  60.     xNext = -GRID_SIZE;        /* Negative direction    */
  61.     yNext = -yNext;
  62.     }
  63.  
  64. /* Calculate the Y coordinate for the current square */
  65. yPos = (((long)xPos - (long)x) * LongTanTable[angle]) + ((long)y << FP_SHIFT);
  66.  
  67. while (1)
  68.     {
  69.     if (xPos < 0 || xPos > GRID_XMAX ||
  70.     yPos < 0 || yPos > GRID_YMAXLONG)
  71.     break;
  72.  
  73. /**************      Fixed point      Y/64 * 64    X / 64 ***********/
  74.     MapPosn = ((yPos >> FP_SHIFT) & 0xFFC0) + (xPos >> 6);
  75.  
  76. /* Check to see if a wall is being struck by the ray */
  77.     if ((Color = ae->xGrid[MapPosn]) != 0)
  78.     {
  79.     xMapPosn = MapPosn;        /* Hold onto the map location */
  80.     iLastX     = xPos;
  81.     LastY1     = yPos;
  82.     if ((Color & 0xFF) == DOOR_XCODE)    /* Is this a door? */
  83.         {
  84.         yd = (yPos >> FP_SHIFT) & 0xFFC0;    /* Get the left side */
  85.         xd = yd + GRID_SIZE;        /* And the right side */
  86.         ObjDist = (yPos + (yNext >> 1)) >> FP_SHIFT; /* Calc door distance */
  87.         if (ObjDist < yd || ObjDist > xd)    /* Is door visible? */
  88.         {
  89.         xPos += xNext;            /* Nope, continue casting */
  90.         yPos += yNext;            /* the ray as before      */
  91.         continue;
  92.         }
  93.  
  94.         LastY1 = yPos + (yNext >> 1);    /* Adjust the X,Y values so   */
  95.         iLastX += (xNext >> 1);        /* the door is halfway in sq. */
  96.         }
  97.  
  98.     if (Color & DOOR_TYPE_SECRET)
  99.         {
  100.         if (xSecretColumn != 0)
  101.         {
  102.         sy = xSecretColumn * LongTanTable[angle];
  103.         ObjDist = (yPos + sy) >> FP_SHIFT;
  104.         yd = (yPos >> FP_SHIFT) & 0xFFC0;   /* Get the left side */
  105.         xd = yd + GRID_SIZE;            /* And the right side */
  106.         if (ObjDist < yd || ObjDist > xd)   /* Is door visible? */
  107.             {
  108.             xPos += xNext;            /* Nope, continue casting */
  109.             yPos += yNext;            /* the ray as before      */
  110.             continue;
  111.             }
  112.         LastY1 = yPos + sy;
  113.         iLastX += xSecretColumn;
  114.         }
  115.         }
  116.  
  117.     xLight = LightMap[MapPosn];
  118.     return(Color);
  119.     }
  120.  
  121.     xPos += xNext;    /* Next X coordinate (fixed at 64 or -64)   */
  122.     yPos += yNext;    /* Next calculated Y coord for a delta of X */
  123.     }
  124.  
  125. return(0);        /* Return that no wall was found */
  126. }
  127.  
  128. /****************************************************************************
  129. ** This routine cast rays along the Y walls of the map to determine when   **
  130. ** a wall is struck. A zero returned indicates no wall was found, else the **
  131. ** bitmap number of the wall is returned.                   **
  132. ** If a wall is found the variables LastX1 and iLastY are set to the map   **
  133. ** coordinates of the wall and xMapPosn is the actual map coordinate.       **
  134. **                                       **
  135. ****************************************************************************/
  136. UINT yRay(int x,int y,int angle,ACKENG *ae)
  137. {
  138.     UINT    Color;
  139.     int        i,j,mx,my;
  140.     int        MapPosn;
  141.     int        yBeg;
  142.     long    yPos,yNext;
  143.     int        BitmapColumn;
  144.     int        xCenter,yCenter,yAdj;
  145.     int        ObjPosn;
  146.     int        oBegX;
  147.     long    xPos;
  148.     long    xNext;
  149.     long    xd,yd,ObjDist,sx;
  150.  
  151. yBeg  = y & 0xFFC0;        /* Same as div 64 then mul 64           */
  152. xNext = xNextTable[angle];    /* Pre-calc'd value of 64 / tan(angle) */
  153.  
  154. if (angle < INT_ANGLE_180)
  155.     {
  156.     yPos  = yBeg + GRID_SIZE;    /* Looking down          */
  157.     yNext = GRID_SIZE;        /* Positive direction */
  158.     }
  159. else
  160.     {
  161.     yPos  = yBeg;        /* Looking up          */
  162.     yNext = -GRID_SIZE;        /* Negative direction */
  163.     xNext = -xNext;
  164.     }
  165.  
  166. /* Calculate the X coordinate for the current square */
  167. xPos = (((long)yPos - (long)y) * LongInvTanTable[angle]) + ((long)x << FP_SHIFT);
  168.  
  169. oBegX = 0;
  170.  
  171. while (1)
  172.     {
  173.     if (xPos < 0 || xPos > GRID_XMAXLONG ||
  174.     yPos < 0 || yPos > GRID_YMAX)
  175.     break;
  176.  
  177. /***********   Y/64 * 64     Fixed point and /64 ******/
  178.     MapPosn = (yPos & 0xFFC0) + (xPos >> (FP_SHIFT+6));
  179.  
  180. /** Check for a wall being struck **/
  181.     if ((Color = ae->yGrid[MapPosn]) != 0)
  182.     {
  183.     yMapPosn = MapPosn;        /* Hold onto map position */
  184.     LastX1     = xPos;
  185.     iLastY     = yPos;
  186.  
  187.     if ((Color & 0xFF) == DOOR_YCODE)     /* Is this a door? */
  188.         {
  189.         yd = (xPos >> FP_SHIFT) & 0xFFC0;    /* Calc top side of square   */
  190.         xd = yd + GRID_SIZE;        /* And bottom side of square */
  191.         ObjDist = (xPos + (xNext >> 1)) >> FP_SHIFT;
  192.         if (ObjDist < yd || ObjDist > xd)    /* Is door visible? */
  193.         {
  194.         xPos += xNext;        /* No, continue on with ray cast */
  195.         yPos += yNext;
  196.         continue;
  197.         }
  198.  
  199.         LastX1 = xPos + (xNext >> 1);   /* Adjust coordinates so door is */
  200.         iLastY += (yNext >> 1);        /* Halfway into wall         */
  201.         }
  202.  
  203.     if (Color & DOOR_TYPE_SECRET)
  204.         {
  205.         if (ySecretColumn != 0)
  206.         {
  207.         sx = ySecretColumn * LongInvTanTable[angle];
  208.         ObjDist = (xPos + sx) >> FP_SHIFT;
  209.         yd = (xPos >> FP_SHIFT) & 0xFFC0;   /* Get the top side       */
  210.         xd = yd + GRID_SIZE;            /* And the bottom side */
  211.         if (ObjDist < yd || ObjDist > xd)   /* Is door visible? */
  212.             {
  213.             xPos += xNext;            /* Nope, continue casting */
  214.             yPos += yNext;            /* the ray as before      */
  215.             continue;
  216.             }
  217.         LastX1 = xPos + sx;
  218.         iLastY += ySecretColumn;
  219.         }
  220.  
  221.         }
  222.  
  223.     yLight = LightMap[MapPosn];
  224.     return(Color);
  225.     }
  226.  
  227.     xPos += xNext;        /* Next calculated X value for delta Y */
  228.     yPos += yNext;        /* Next fixed value of 64 or -64       */
  229.  
  230.     if (++oBegX > 64)        /* Check a maximum number of squares   */
  231.     break;
  232.     }
  233.  
  234. return(0);        /* Return here if no Y wall is found */
  235. }
  236.  
  237.